package com.bubblegumproject.ogo.remote.tunnel;

import com.bubblegumproject.ogo.remote.OgoRemoteException;

import java.net.URL;
import java.net.HttpURLConnection;
import java.io.*;

/**
 * Tunnel that will send/receive Actions using HTTP as the underlying transport protocol.
 *
 * @author Azubuko Obele (buko.obele@gmail.com)
 */
public class HttpTunnel implements Tunnel {

    private URL reactorUrl;

    public HttpTunnel(URL reactorUrl) {
        assert(reactorUrl != null);
        this.reactorUrl = reactorUrl;
        HttpURLConnection.setFollowRedirects(false);
    }

    public TunnelResponse send(TunnelRequest request) {
        assert(request != null);
        try {
            HttpURLConnection connection = (HttpURLConnection) reactorUrl.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setInstanceFollowRedirects(false);
            write(request, connection.getOutputStream());

            TunnelResponse response = read(connection.getInputStream());
            return response;
        } catch (IOException ioe) {
            throw new OgoRemoteException(this + " failed to send request " + request, ioe);
        }
    }

    private void write(TunnelRequest request, OutputStream output) throws IOException {
        ObjectOutputStream objectOut = new ObjectOutputStream(output);
        objectOut.writeObject(request);
        objectOut.flush();
    }

    private TunnelResponse read(InputStream in) throws IOException {
        ObjectInputStream objectIn = new ObjectInputStream(in);
        try {
            return (TunnelResponse) objectIn.readObject();
        } catch (ClassNotFoundException cnfe) {
            throw new IOException(this + " got class error " + cnfe, cnfe);
        }
    }
}
